'''
Created on 6 Apr 2011

@author: LowG
'''

import unittest

from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.ext import testbed

from models import CDISC_ControlledTerminology, CDISC_Codelist, \
CDISC_CodeListItem, Organisation, Controlled_Terminology_Source 


class framework_Test(unittest.TestCase):

  def setUp(self):
    """
    From: http://code.google.com/appengine/docs/python/tools/localunittesting.html
    """
    # First, create an instance of the Testbed class.
    self.testbed = testbed.Testbed()
    # Then activate the testbed, which prepares the service stubs for use.
    self.testbed.activate()
    # Next, declare which service stubs you want to use.
    self.testbed.init_datastore_v3_stub()
    self.testbed.init_memcache_stub()

  def tearDown(self):
    self.testbed.deactivate()

class Test_Organisation(framework_Test):

  def test_AddOrganisation(self):
    organisation = Organisation(name='CDISC')
    organisation.put()
    self.assertEqual(1, len(Organisation.all().fetch(2)))


class Test_Controlled_Terminology_Source(framework_Test):
  
  def test_AddSource(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name="SDTM Controlled Terminology",
                                           organisation = organisation,
                                           filename="SDTM Controlled Terminology.xls")
    source.description = "SDTM Controlled Terminology"
    source.put()
    self.assertEqual(1, len(Controlled_Terminology_Source.all().fetch(2)))
    

class Test_CDISC_Controlled_Terminology_Codelist(framework_Test):
  
  
  def test_AddCode(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name = "SDTM Controlled Terminology",
                                           description = "SDTM Controlled Terminology",
                                           filename = "SDTM Controlled Terminology.xls",
                                           organisation = organisation)
    
    source.put()
    ct = CDISC_Codelist(ExternalCodeID = 'C12345',
                        CDISCSubmissionValue = 'CODED TERM',
                        Description = "Some Definition",
                        Name = 'CODELIST',
                        Extensible = False,
                        CDISCSynonyms = ['1', '2'],
                        Draft = False,
                        PreferredTerm = 'Coded term',
                        Source = source)
    ct.put()
    self.assertEqual(1, len(CDISC_Codelist.all().fetch(2)))

  def test_Query(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name="SDTM Controlled Terminology",
                                           description = "SDTM Controlled Terminology",
                                           filename="SDTM Controlled Terminology.xls",
                                           organisation = organisation)
    
    source.put()
    # have created the source
    ct = CDISC_Codelist(ExternalCodeID = 'C12345',
                      CDISCSubmissionValue = 'CODED TERM',
                      Description = "Some Definition",
                      name = 'CODELIST',
                      Extensible = False,
                      CDISCSynonyms = ['1', '2'],
                      Draft = False,
                      PreferredTerm = 'Coded term',
                      Source = source)
    ct.put()
    self.assertEqual(1, len(CDISC_Codelist.all().fetch(2)))
    cl = CDISC_ControlledTerminology.gql("WHERE ExternalCodeID = :1", 'C12345').fetch(1)[0]
    self.assertEqual('CDISC', cl.Source.organisation.name)

class Test_CDISC_Controlled_Terminology_CodelistItem(framework_Test):
  
  
  def test_AddCodeItem(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name="SDTM Controlled Terminology",
                                           description = "SDTM Controlled Terminology",
                                           filename="SDTM Controlled Terminology.xls",
                                           organisation = organisation)
    
    source.put()
    ct = CDISC_Codelist(ExternalCodeID = 'C12345',
                        CDISCSubmissionValue = 'CODED TERM',
                        Description = "Some Definition",
                        Name = 'CODELIST',
                        Extensible = False,
                        CDISCSynonyms = ['1', '2'],
                        Draft = False,
                        PreferredTerm = 'Coded term',
                        Source = source)
    ct.put()
    cti = CDISC_CodeListItem(code='C12346',
                             CDISCSubmissionValue = 'CODED ITEM 1',
                             Description = "Some Definition 1",
                             Name = 'CODED ITEM 1',
                             CDISCSynonyms = ['3', '5'],
                             PreferredTerm = 'Coded item 1',
                             Source = source
                             )
    cti.Codelists.append(ct.key())
    cti.put()
    self.assertEqual(1, len(ct.coded_items))
    ctj = CDISC_CodeListItem(ExternalCodeID='C12347',
                             CDISCSubmissionValue = 'CODED ITEM 2',
                             Description = "Some Definition 2",
                             Name = 'CODED ITEM 2',
                             CDISCSynonyms = ['3'],
                             PreferredTerm = 'Coded item 2',
                             Source = source)
    ctj.Codelists.append(ct.key())
    ctj.put()
    self.assertEqual(2, len(ct.coded_items))
    
  def test_AddCodeItem_to_two_Codelists(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name="SDTM Controlled Terminology",
                                           description = "SDTM Controlled Terminology",
                                           filename="SDTM Controlled Terminology.xls",
                                           organisation = organisation)
    
    source.put()
    # create a codelist
    ct = CDISC_Codelist(ExternalCodeID = 'C12345',
                        CDISCSubmissionValue = 'CODED TERM',
                        CDISCDefinition = "Some Definition",
                        Name = 'CODELIST',
                        Extensible = False,
                        CDISCSynonyms = ['1', '2'],
                        Draft = False,
                        PreferredTerm = 'Coded term',
                        Source = source)
    ct.put()
    # create a second codelist
    ct2 = CDISC_Codelist(ExternalCodeID = 'C12345',
                         CDISCSubmissionValue = 'CODED TERM',
                         CDISCDefinition = "Some Definition",
                         Name = 'CODELIST',
                         Extensible = False,
                         CDISCSynonyms = ['1', '2'],
                         Draft = False,
                         PreferredTerm = 'Coded term',
                         Source = source)
    ct2.put()
    # create an item
    cti = CDISC_CodeListItem(code='C12346',
                             CDISCSubmissionValue = 'CODED ITEM 1',
                             CDISCDefinition = "Some Definition 1",
                             CDISCSynonyms = ['3', '5'],
                             PreferredTerm = 'Coded item 1',
                             Source = source)
    # allocate the item to the two codelists
    cti.Codelists.extend([ct.key(), ct2.key()])
    cti.put()
    self.assertEqual(1, len(ct.coded_items))
    self.assertEqual(1, len(ct2.coded_items))
    ctj = CDISC_CodeListItem(code='C12347',
                             CDISCSubmissionValue = 'CODED ITEM 2',
                             CDISCDefinition = "Some Definition 2",
                             CDISCSynonyms = ['3'],
                             PreferredTerm = 'Coded item 2',
                             Source = source)
    ctj.Codelists.append(ct.key())
    ctj.put()
    self.assertEqual(2, len(ct.coded_items))
  
  def test_UpdateCodeItem(self):
    organisation = Organisation()
    organisation.name='CDISC'
    organisation.put()
    source = Controlled_Terminology_Source(name="SDTM Controlled Terminology",
                                           description = "SDTM Controlled Terminology",
                                           filename="SDTM Controlled Terminology.xls",
                                           organisation = organisation)
    
    source.put()
    # create a codelist
    ct = CDISC_Codelist(ExternalCodeID = 'C12345',
                        CDISCSubmissionValue = 'CODED TERM',
                        CDISCDefinition = "Some Definition",
                        Name = 'CODELIST',
                        Extensible = False,
                        CDISCSynonyms = ['1', '2'],
                        Draft = False,
                        PreferredTerm = 'Coded term',
                        Source = source)
    ct.put()
    cti = CDISC_CodeListItem(ExternalCodeID = 'C12346',
                             CDISCSubmissionValue = 'CODED ITEM 1',
                             CDISCDefinition = "Some Definition 1",
                             CDISCSynonyms = ['3', '5'],  
                             PreferredTerm = 'Coded item 1',
                             Source = source)
    cti.Codelists.append(ct.key())
    cti.put()
    print cti.ExternalCodeID
    self.assertEqual('CODED ITEM 1', 
                     CDISC_CodeListItem.gql("WHERE ExternalCodeID = :1", 
                                            'C12346').fetch(1)[0].CDISCSubmissionValue)
    updated_cti = CDISC_CodeListItem.gql("WHERE ExternalCodeID = :1", 'C12346').fetch(1)[0]
    updated_cti.CDISCSubmissionValue = 'CODED ITEM 1.1'
    updated_cti.put()
    self.assertEqual('CODED ITEM 1.1', 
                     CDISC_CodeListItem.gql("WHERE ExternalCodeID = :1", 'C12346').fetch(1)[0].CDISCSubmissionValue)
    
if __name__ == "__main__":
  unittest.main(verbosity=2)
  